🎖️GitЯра🎖️
Node / meshtastic / Meshtastic-Android / files / androidApp / src / google / kotlin / org / meshtastic / app / map / offline / terrain / ElevationStitcher.kt
Displaying Raw • Download
androidApp/src/google/kotlin/org/meshtastic/app/map/offline/terrain/ElevationStitcher.kt renovate/fastlane-2.x-lockfile (056eed64) Text, 4.19 KB
T8b949e/*
* Copyright (c) 2026 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
Tff7b72package T7ee787org.meshtastic.app.map.offline.terrain
Tff7b72import T7ee787org.meshtastic.feature.map.terrain.ElevationTile
Tff7b72import T7ee787org.meshtastic.feature.map.terrain.Hillshade
T8b949e/**
* Assembles the margin-padded [ElevationTile] [Hillshade.shade] needs from a center tile plus whichever of its 8
* neighbors are available — the counterpart to the sibling iOS app's `TerrainStore.elevationTile(margin:)`.
*
* Every padding pixel is pulled from the neighbor tile whose edge actually borders it (e.g. the padded tile's top-left
* corner comes from the NW-diagonal neighbor's own bottom-right pixel). Where that neighbor wasn't downloaded — most
* commonly at the edge of a downloaded region, where there is no tile beyond it at all — this falls back to [center]'s
* own [ElevationTile.elevationAt], which already clamps out-of-range coordinates to the tile's own edge. That is the
* same graceful-degradation spirit the task calls for: clamp, don't crash or fabricate data.
*
* Pure and I/O-free by design so it's unit-testable without decoding real Terrarium bytes: [HillshadeTileProvider] owns
* fetching and decoding the neighbor tiles this takes.
*/
Tff7b72internal Tff7b72object T56d364ElevationStitcher Tb4b4b4{
T8b949e/** [center]'s own 8 neighbor tiles, keyed by `(dx, dy)` in `{-1,0,1}²` — absent means "not downloaded". */
Tff7b72fun Td2a8ffbuildPaddedTb4b4b4(Te6edf3centerTb4b4b4: Te6edf3ElevationTileTb4b4b4, Te6edf3neighborsTb4b4b4: Te6edf3MapTff7b72<Te6edf3PairTff7b72<Tffa657IntTb4b4b4, Tffa657IntTff7b72>Tb4b4b4, Te6edf3ElevationTileTff7b72>Tb4b4b4)Tb4b4b4: Te6edf3ElevationTile Tb4b4b4{
Tff7b72val Te6edf3margin Tff7b72= Te6edf3HillshadeTb4b4b4.Te6edf3MARGIN
Tff7b72val Te6edf3paddedWidth Tff7b72= Te6edf3centerTb4b4b4.Te6edf3width Tff7b72+ T79c0ff2 Tff7b72* Te6edf3margin
Tff7b72val Te6edf3paddedHeight Tff7b72= Te6edf3centerTb4b4b4.Te6edf3height Tff7b72+ T79c0ff2 Tff7b72* Te6edf3margin
Tff7b72val Te6edf3elevations Tff7b72= Te6edf3FloatArrayTb4b4b4(Te6edf3paddedWidth Tff7b72* Te6edf3paddedHeightTb4b4b4)
Tff7b72for Tb4b4b4(Te6edf3py Tff7b72in Tff7b72-Te6edf3marginTb4b4b4.Tb4b4b4.Te6edf3centerTb4b4b4.Te6edf3heightTb4b4b4) Tb4b4b4{
Tff7b72for Tb4b4b4(Te6edf3px Tff7b72in Tff7b72-Te6edf3marginTb4b4b4.Tb4b4b4.Te6edf3centerTb4b4b4.Te6edf3widthTb4b4b4) Tb4b4b4{
Te6edf3elevationsTff7b72[Tb4b4b4(Te6edf3py Tff7b72+ Te6edf3marginTb4b4b4) Tff7b72* Te6edf3paddedWidth Tff7b72+ Tb4b4b4(Te6edf3px Tff7b72+ Te6edf3marginTb4b4b4)Tff7b72] Tff7b72= Te6edf3elevationAtTb4b4b4(Te6edf3centerTb4b4b4, Te6edf3neighborsTb4b4b4, Te6edf3pxTb4b4b4, Te6edf3pyTb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tff7b72return Te6edf3ElevationTileTb4b4b4(Te6edf3paddedWidthTb4b4b4, Te6edf3paddedHeightTb4b4b4, Te6edf3elevationsTb4b4b4)
Tb4b4b4}
T8b949e/** [px]/[py] are in [center]'s own local coordinate space, extended past its edges into padding territory. */
Tff7b72private Tff7b72fun Td2a8ffelevationAtTb4b4b4(
Te6edf3centerTb4b4b4: Te6edf3ElevationTileTb4b4b4,
Te6edf3neighborsTb4b4b4: Te6edf3MapTff7b72<Te6edf3PairTff7b72<Tffa657IntTb4b4b4, Tffa657IntTff7b72>Tb4b4b4, Te6edf3ElevationTileTff7b72>Tb4b4b4,
Te6edf3pxTb4b4b4: Tffa657IntTb4b4b4,
Te6edf3pyTb4b4b4: Tffa657IntTb4b4b4,
Tb4b4b4)Tb4b4b4: Tffa657Float Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3px Tff7b72in T79c0ff0 Te6edf3until Te6edf3centerTb4b4b4.Te6edf3width Tff7b72&Tff7b72& Te6edf3py Tff7b72in T79c0ff0 Te6edf3until Te6edf3centerTb4b4b4.Te6edf3heightTb4b4b4) Tff7b72return Te6edf3centerTb4b4b4.Te6edf3elevationAtTb4b4b4(Te6edf3pxTb4b4b4, Te6edf3pyTb4b4b4)
Tff7b72val Te6edf3dx Tff7b72=
Tff7b72if Tb4b4b4(Te6edf3px Tff7b72< T79c0ff0Tb4b4b4) Tb4b4b4{
Tff7b72-T79c0ff1
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3px Tff7b72>Tff7b72= Te6edf3centerTb4b4b4.Te6edf3widthTb4b4b4) Tb4b4b4{
T79c0ff1
Tb4b4b4} Tff7b72else Tb4b4b4{
T79c0ff0
Tb4b4b4}
Tff7b72val Te6edf3dy Tff7b72=
Tff7b72if Tb4b4b4(Te6edf3py Tff7b72< T79c0ff0Tb4b4b4) Tb4b4b4{
Tff7b72-T79c0ff1
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3py Tff7b72>Tff7b72= Te6edf3centerTb4b4b4.Te6edf3heightTb4b4b4) Tb4b4b4{
T79c0ff1
Tb4b4b4} Tff7b72else Tb4b4b4{
T79c0ff0
Tb4b4b4}
Tff7b72val Te6edf3neighbor Tff7b72= Te6edf3neighborsTff7b72[Te6edf3dx Te6edf3to Te6edf3dyTff7b72]
Tff7b72return Tff7b72if Tb4b4b4(Te6edf3neighbor Tff7b72=Tff7b72= Tff7b72nullTb4b4b4) Tb4b4b4{
Te6edf3centerTb4b4b4.Te6edf3elevationAtTb4b4b4(Te6edf3pxTb4b4b4, Te6edf3pyTb4b4b4) T8b949e// No neighbor there: clamps to center's own edge.
Tb4b4b4} Tff7b72else Tb4b4b4{
T8b949e// dx/dy == 0 means px/py is already within center's own range (the interior check above would have
T8b949e// returned), so the `else` branch below is only ever reached with an in-range coordinate on that axis.
Tff7b72val Te6edf3localX Tff7b72=
Tff7b72when Tb4b4b4(Te6edf3dxTb4b4b4) Tb4b4b4{
Tff7b72-T79c0ff1 Tff7b72-Tff7b72> Te6edf3neighborTb4b4b4.Te6edf3width Tff7b72- T79c0ff1
T79c0ff1 Tff7b72-Tff7b72> T79c0ff0
Tff7b72else Tff7b72-Tff7b72> Te6edf3px
Tb4b4b4}
Tff7b72val Te6edf3localY Tff7b72=
Tff7b72when Tb4b4b4(Te6edf3dyTb4b4b4) Tb4b4b4{
Tff7b72-T79c0ff1 Tff7b72-Tff7b72> Te6edf3neighborTb4b4b4.Te6edf3height Tff7b72- T79c0ff1
T79c0ff1 Tff7b72-Tff7b72> T79c0ff0
Tff7b72else Tff7b72-Tff7b72> Te6edf3py
Tb4b4b4}
Te6edf3neighborTb4b4b4.Te6edf3elevationAtTb4b4b4(Te6edf3localXTb4b4b4, Te6edf3localYTb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Served by rngit 1.5.3 - Generated in 0.09s